package basicelement;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import com.rapidminer.example.Attribute;
import com.rapidminer.example.Attributes;
import com.rapidminer.example.ExampleSet;

import com.rapidminer.example.Example;
import com.rapidminer.example.table.AttributeFactory;


import istar.IElement;
import istar.ITask;
import istar.agent.IstarJadeAgent;
import istar.behaviour.AbstractIstarBehaviour;
import istar.impl.AbstractBasicTask;
import istar.impl.Belief;
import istar.impl.MeansEndLink;
import istar.impl.Task;
import istar.impl.TaskDecompositionLink;
import jade.core.Agent;
import jade.core.behaviours.Behaviour;
import jade.core.behaviours.OneShotBehaviour;
import jade.lang.acl.ACLMessage;


public class Ponder extends AbstractBasicTask{

	private boolean log = true;
	
	public Ponder() {
		super("Ponder"); 
	}

	@Override
	public Behaviour getBehaviour() {
		return new myBehaviour(this);
	}
	
	private class myBehaviour extends AbstractIstarBehaviour{

		private int estimatedTime = 100;
		
		/*
		public myBehaviour(Agent a, AbstractBasicTask _task){
			super(a);
			task = _task;
			this.setBehaviourName("Ponder");
		}
		*/

		@Override
		public long getEstimatedWaitingTime() {
			return estimatedTime;
		}

		public myBehaviour(AbstractBasicTask _task){
			super(_task);
		}

		
		@Override
		public void myAction() {
			
			try {
				System.out.println(myAgent.getLocalName() +  " >>>> Starting Ponder");
				log("Starting Ponder");
				TendencyIndicator tendency = null;
				//changed here
				//IElement obtainTendency = (IElement)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "ObtainTendency");
				//for (int i=0;i<obtainTendency.getContent().size();i++){
				//	if (obtainTendency.getContent().get(i).getClass().equals(TendencyIndicator.class))
				//		tendency = (TendencyIndicator)obtainTendency.getContent().get(i);
				//}
				
				ArrayList<Object> result = (ArrayList<Object>)((IstarJadeAgent)myAgent).getResult(getElement().getExecutionNumber(), "ObtainTendency");
				tendency = (TendencyIndicator)result.get(0);
				if (tendency==null)
					throw new Exception("Tendency not found");

				
				((IstarJadeAgent)myAgent).getShortTermMemory().put(tendency.getInstantTime().toString(), tendency);

				System.out.println("Tendency:" + tendency.toString());
				Belief futurePrice = null;
				
				Iterator<TaskDecompositionLink> itDecompositionLinks = ((AbstractBasicTask)getElement()).getSupports().iterator();
				while (itDecompositionLinks.hasNext()){
					IElement father = itDecompositionLinks.next().getOwner();
					if (father.getName().equals("GenerateBelief")){
						Iterator<MeansEndLink> itMeansEnds = ((Task)father).getMeansFor().iterator();
						while (itMeansEnds.hasNext()){
							IElement grandFather = itMeansEnds.next().getOwner();
							if (grandFather.getName().equals("FuturePrice"))
								futurePrice = (Belief)grandFather;
						}
					}
				}
				
				//System.out.println("Future Price content: " + futurePrice.getContent().toString());

				((IstarJadeAgent)myAgent).getBeliefs().remove(futurePrice);
				IElement actionBeChosen = (IElement)futurePrice.getEvaluationLink().getTargetGoal();
				Iterator<IElement> itMeans = actionBeChosen.getMeansEndLink().getTargetElements().iterator();
				while (itMeans.hasNext()){
					ITask mean = (ITask)itMeans.next();
					Double eval = evaluateMeanTask(tendency, mean);
					System.out.println("============");
					System.out.println("Mean:" + mean.getName() + " - eval:" + eval);
					futurePrice.getAssessments().put(mean, eval);
				}
				
				((IstarJadeAgent)myAgent).getBeliefs().add(futurePrice);
				
				
				
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
		
		/*
		private Double evaluateMeanTask(TendencyIndicator tendency, ITask mean){
			try {
				Date instant = tendency.getInstantTime(); 
				Calendar cal = Calendar.getInstance();
				cal.setTime(instant);
				int previousMinute = cal.get(Calendar.MINUTE);
				int hour =  cal.get(Calendar.HOUR);
				int day = cal.get(Calendar.DAY_OF_MONTH);
				int month = cal.get(Calendar.MONTH) + 1;
				int year = cal.get(Calendar.YEAR);
				
				previousMinute --;
				
				String prev = day+"/"+month+"/"+year+" "+hour+":"+previousMinute;
				Date previousInstant = TendencyIndicator.formatDate(prev);
				
				TendencyIndicator previousTendency = (TendencyIndicator)((IstarJadeAgent)myAgent).getShortTermMemory().get(previousInstant.toString());
				if (previousTendency!=null){
					if (previousTendency.getTendency()==tendency.getTendency()){
						if (tendency.getTendency()>0){
							if (mean.getName().toUpperCase().equals("BUY"))
								return new Double(tendency.getTendency());
							else
								return new Double(-tendency.getTendency());
						}
						if (tendency.getTendency()<0){
							if (mean.getName().toUpperCase().equals("SELL"))
								return new Double(-tendency.getTendency());
							else
								return new Double(tendency.getTendency());
						}
					}
				}
				
				if (mean.getName().equals("DoNothing"))
					return new Double(1);
				else
					return new Double(0);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return new Double(Belief.NEUTRAL);
		}
		*/
		
		private Double evaluateMeanTask(TendencyIndicator tendency, ITask mean){
			try {

				MarketPosition myCurrentPosition = (MarketPosition) ((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "CurrentPosition");

				
				/*
				
				Example stockOptionPrices = null;
				IElement stockOptionQuotation = (IElement)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "ObtainStockOptionQuotation");
				for (int i=0;i<stockOptionQuotation.getContent().size();i++){
					if (stockOptionQuotation.getContent().get(i).getClass().equals(Example.class))
						stockOptionPrices = (Example)stockOptionQuotation.getContent().get(i);
				}
				if (stockOptionPrices==null)
					throw new Exception("StockOptionPrices not found");

				Attribute lowStockAtt = stockOptionPrices.getAttributes().get(myCurrentPosition.getLowStockOptionName());
				Double lowStockPrice = stockOptionPrices.getValue(lowStockAtt);
				
				Attribute highStockAtt = stockOptionPrices.getAttributes().get(myCurrentPosition.getHighStockOptionName());
				Double highStockPrice = stockOptionPrices.getValue(highStockAtt);

				System.out.println("stockoption prices: "+ myCurrentPosition.getLowStockOptionName() + "=" + lowStockPrice + ";"+
														   myCurrentPosition.getHighStockOptionName() + "="+ highStockPrice);

				((IstarJadeAgent)myAgent).setKnowledgeObject(getElement().getExecutionNumber(), "HighStockPrice", highStockPrice);
				((IstarJadeAgent)myAgent).setKnowledgeObject(getElement().getExecutionNumber(), "LowStockPrice", lowStockPrice);
				*/
				
				Date instant = tendency.getInstantTime(); 
				Calendar cal = Calendar.getInstance();
				cal.setTime(instant);
				int previousMinute = cal.get(Calendar.MINUTE);
				int hour =  cal.get(Calendar.HOUR);
				int day = cal.get(Calendar.DAY_OF_MONTH);
				int month = cal.get(Calendar.MONTH) + 1;
				int year = cal.get(Calendar.YEAR);
				
				previousMinute --;
			//	Double money = (Double)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "Money");
			//	Double lowStockPriceOrdered = (Double)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "LowStockPriceOrdered");
			//	Double highStockPriceOrdered = (Double)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "HighStockPriceOrdered");

				//long qttLowStock = myCurrentPosition.getQttLowStockOption();
				//Integer qttHighStock = (Integer)((IstarJadeAgent)myAgent).getKnowledgeElement(getElement().getExecutionNumber(), "HighStockQtt");
				
				
				String prev = day+"/"+month+"/"+year+" "+hour+":"+previousMinute;
				Date previousInstant = TendencyIndicator.formatDate(prev);
				
				TendencyIndicator previousTendency = (TendencyIndicator)((IstarJadeAgent)myAgent).getShortTermMemory().get(previousInstant.toString());
				if (previousTendency!=null){
					if (previousTendency.getTendency()==tendency.getTendency()){
						// Positive tendency
						if (tendency.getTendency()>0){
							if (mean.getName().toUpperCase().equals("BUY")){
								// bought
								if (myCurrentPosition.getPosition()==MarketPosition.BOUGHT){
									return new Double (0);
								}
								else {
									return new Double(tendency.getTendency());
								}
							}
							
							if (mean.getName().toUpperCase().equals("SELL")){
								return new Double (0);
							}
							
							if (mean.getName().equals("DoNothing")){
								// bought
								if (myCurrentPosition.getPosition()==MarketPosition.BOUGHT){
									return new Double (1);
								}
								else {
									return new Double(0);
								}
							}

						}
						//Negative tendency
						if (tendency.getTendency()<0){
							if (mean.getName().toUpperCase().equals("SELL")){
								// sold
								if (myCurrentPosition.getPosition()==MarketPosition.SOLD){
									return new Double (0);
								}
								else {
									return new Double(-tendency.getTendency());
								}
							}
							
							if (mean.getName().toUpperCase().equals("BUY")){
								return new Double (0);
							}
							
							if (mean.getName().equals("DoNothing")){
								// sold
								if (myCurrentPosition.getPosition()==MarketPosition.SOLD){
									return new Double (1);
								}
								else {
									return new Double(0);
								}
							}
						}
						
					}
					// tendency changed
					else {
						if (mean.getName().equals("DoNothing"))
							return new Double(1);
						else
							return new Double(0);
					}
				}
				
				
				if (mean.getName().equals("DoNothing"))
					return new Double(1);
				else
					return new Double(0);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return new Double(Belief.NEUTRAL);
		}
		
		private boolean checkStopGain(){
			return false;
			
		}

		private boolean checkStopLoss(){
			return false;
			
		}

		
		@Override
		public int myOnEnd() {
			// TODO Auto-generated method stub
			return 1;
		}

		@Override
		public boolean done() {
			return true;
		}

	}
	
}
